﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AYA.Core.Cache
{
    internal class CacheItem:IDisposable
    {
        private object _value;

        /// <summary>
        /// 取得缓存的值
        /// </summary>
        public object Value
        {
            get
            {
                if (this.IsExpirated)
                {                    
                    return null;
                }
                else
                {
                    _lastAccessedTime = DateTime.Now;
                    return _value;
                }
            }
            set
            {
                _lastAccessedTime = DateTime.Now;
                _value = value;
            }
        }
        private DateTime _createTime;
        private DateTime _lastAccessedTime;
        private int _expirationSecond=-1;
        private int _absoluteExpirationSecond=-1;
        private bool _dependcyFileChanged;
        System.IO.FileSystemWatcher watcher;
        private log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public CacheItem(object value,int expirationSecond, int absoluteExpirationSecond,  string dependencyFilePath)
        {
            _value = value;
            _createTime = DateTime.Now;
            _lastAccessedTime = DateTime.Now;
            _dependcyFileChanged = false;
            _expirationSecond = expirationSecond;
            _absoluteExpirationSecond = absoluteExpirationSecond;
            if (!string.IsNullOrEmpty(dependencyFilePath))
            {
                if (System.IO.File.Exists(dependencyFilePath))
                {
                    System.IO.FileInfo fi = new System.IO.FileInfo(dependencyFilePath);
                    watcher = new System.IO.FileSystemWatcher(fi.DirectoryName,fi.Name);
                    watcher.Changed += new System.IO.FileSystemEventHandler(watcher_Changed);
                    watcher.EnableRaisingEvents = true;


                }
                else
                {
                    log.Error("声明了缓存依赖文件,但该文件不存在." + dependencyFilePath);
                    //throw new Exception("声明了缓存依赖文件,但该文件不存在.");
                }
            }

        }

        public CacheItem(object value, string dependencyFilePath):this(value,-1,-1,dependencyFilePath){}
        public CacheItem(object value, int expirationSecond, string dependencyFilePath) : this(value, expirationSecond, -1, dependencyFilePath) { }

        void watcher_Changed(object sender, System.IO.FileSystemEventArgs e)
        {
            this._dependcyFileChanged = true;
            this._value = null;
        }

        /// <summary>
        /// 指示该项是否已经过期
        /// </summary>
        public bool IsExpirated
        {
            get
            {
                if (_dependcyFileChanged)
                    return true;
                if (_absoluteExpirationSecond!=-1 && _createTime.AddSeconds(_absoluteExpirationSecond) < DateTime.Now)
                    return true;
                if (_absoluteExpirationSecond == -1 && _lastAccessedTime.AddSeconds(_expirationSecond) < DateTime.Now)
                    return true;
                return false;
            }
        }

        #region IDisposable 成员

        public void Dispose()
        {
            this._value = null;
            watcher.Dispose();

        }

        #endregion
    }
}
